/**
 * 
 */
package edu.arizona.bio5.onto.decomposition.persistent.rdf;

import org.coode.owlapi.rdfxml.parser.OWLRDFConsumer;
import org.openrdf.model.Literal;
import org.openrdf.model.Resource;
import org.openrdf.model.Statement;
import org.openrdf.model.URI;
import org.openrdf.model.Value;
import org.openrdf.model.ValueFactory;
import org.openrdf.model.vocabulary.OWL;
import org.openrdf.rio.RDFHandler;
import org.openrdf.rio.RDFHandlerException;
import org.semanticweb.owlapi.io.RDFXMLOntologyFormat;
import org.semanticweb.owlapi.model.IRI;
import org.semanticweb.owlapi.model.OWLDataFactory;
import org.semanticweb.owlapi.model.OWLEntity;
import org.xml.sax.SAXException;

import edu.arizona.bio5.onto.decomposition.Atom;

/**
 * @author Pavel Klinov
 * 
 */
public class SesameOWLRDFUtils {

	public static URI getAtomURI(Atom atom, ValueFactory factory) {
		return factory.createURI(RDFADConstants.AD_ATOM_INSTANCE + atom.getID());
	}
	
	
	public static String termToURI(OWLEntity term) {
		String uri = term.toStringID();

		if (term.isOWLClass()) {
			uri = OWL.CLASS + "/" + uri;

		} else if (term.isOWLObjectProperty()) {
			uri = OWL.OBJECTPROPERTY + "/" + uri;

		} else if (term.isOWLDataProperty()) {

			uri = OWL.DATATYPEPROPERTY + "/" + uri;
		}

		return uri;
	}

	public static OWLEntity termFromURI(OWLDataFactory factory, String termURI) {
		OWLEntity term = null;

		if (termURI.startsWith(OWL.CLASS.toString())) {

			term = factory.getOWLClass(IRI.create(termURI.substring(OWL.CLASS
					.toString().length() + 1)));

		} else if (termURI.startsWith(OWL.OBJECTPROPERTY.toString())) {

			term = factory.getOWLObjectProperty(IRI.create(termURI
					.substring(OWL.OBJECTPROPERTY.toString().length() + 1)));

		} else if (termURI.startsWith(OWL.DATATYPEPROPERTY.toString())) {

			term = factory.getOWLDataProperty(IRI.create(termURI
					.substring(OWL.DATATYPEPROPERTY.toString().length() + 1)));
		}

		return term;
	}	

	static class OWLAPIHandler implements RDFHandler {

		final OWLRDFConsumer mConsumer;
		Exception mFirstError;

		OWLAPIHandler(OWLRDFConsumer consumer) {
			mConsumer = consumer;
		}

		@Override
		public void endRDF() throws RDFHandlerException {
			
			try {
				mConsumer.endModel();
			} catch (SAXException e) {
				e.printStackTrace();
				mFirstError = mFirstError == null ? e : mFirstError;
			}
			
			if (mFirstError != null) {
				throw new RDFHandlerException(mFirstError);
			}
		}

		@Override
		public void handleComment(String arg0) throws RDFHandlerException {
		}

		@Override
		public void handleNamespace(String arg0, String arg1) throws RDFHandlerException {
		}

		@Override
		public void handleStatement(Statement stmt) throws RDFHandlerException {
			
			Resource subject = stmt.getSubject();
			URI predicate = stmt.getPredicate();
			Value object = stmt.getObject();
			
			if (OWL.IMPORTS.stringValue().equals(predicate.stringValue())) {
				return;
			}
			
			if (subject == null) return;
			
			try {
				if (object instanceof Literal) {
					Literal literal = (Literal) object;
					String dt = literal.getDatatype() == null ? null : literal.getDatatype().stringValue();
					
					mConsumer.statementWithLiteralValue(subject.stringValue(), predicate.stringValue(), object.stringValue(), literal.getLanguage(), dt);
				}
				else {
					mConsumer.statementWithResourceValue(subject.stringValue(), predicate.stringValue(), object.stringValue());
				}
			} catch (SAXException e) {
				e.printStackTrace();
				mFirstError = mFirstError == null ? e : mFirstError;
			}
		}

		@Override
		public void startRDF() throws RDFHandlerException {
			mConsumer.setOntologyFormat(new RDFXMLOntologyFormat());
			
			try {
				mConsumer.startModel("");
			} catch (SAXException e) {
				mFirstError = mFirstError == null ? e : mFirstError;
			}
		}
	}
	
	
	
}